######################################### IMPORTING LIBRARIES #########################################

from opencv.cv import *
from opencv.highgui import *
from BlobResult import *
from Blob import *
from pymouse import *
import time
import sys

######################################### 
# Initializing the webcamera.
capture = cvCreateCameraCapture(0) 
# Starting the Graphical interface thread.
cvStartWindowThread() 
# Create Pymouse object.
m = PyMouse()
print m.screen_size()
image = None

print "Capturing frames.. Press ESC to Quit."

while 1:
    c = cvWaitKey(10)
    if  c == '\x1b' :
        exit()

    # Capturing frame
    frame =cvQueryFrame (capture) 
    
    if frame is None:
            # no image captured... end the processing
	    print "no frame"
            break

    if image is None:
            # create the images we need
            image = cvCreateImage (cvGetSize (frame), 8, 3)
            red = cvCreateImage (cvGetSize (frame), 8, 1)
            blue = cvCreateImage (cvGetSize (frame), 8, 1)
            green = cvCreateImage (cvGetSize (frame), 8, 1)

    # Flip the frame as webcam image will be mirrored    
    cvFlip(frame,0,1) 
    
    # Copy the frame, so we can draw on it
    cvCopy (frame, image) 
    
    
    # Open a window
    cvNamedWindow("Webcam") 
     
    # Show Image in the opened window
    cvShowImage("Webcam",image) 
    
    
    # Extracting the red channel
    cvSplit(image, blue, green, red, None)
    cvAdd(blue, green, green)
    cvSub(red, green, red)
######################################## EXTRACTING BLOBS ################################################################
    
    # Perform an OTSU threshold to prepare a binary image.
    cvThreshold(red, red, 20, 255, CV_THRESH_OTSU)
    binary_image = cvCreateMat(red.rows,red.cols,red.type)
    cvThreshold(red, binary_image, 100, 255, CV_THRESH_OTSU)
    
    # Get the frame size.
    frame_size = cvGetSize (red)
    
    # Create necessary data structures for holding the blobs and masking the image.
    blob= cvCreateImage(frame_size, 8, 1)
    mask = cvCreateImage (frame_size, 8, 1)
    cvSet(mask, 255)
    
    # Extracting the blobs
    myblobs = CBlobResult(binary_image, mask, 0, True)
    myblobs.filter_blobs(1500,3500)
 
    # Get the numberof blobs
    blob_count = myblobs.GetNumBlobs()

#################################  CALCULATING CORDINATES FOR MOVEMENT ###################################################################

    if blob_count==0:
       continue 
    cvSet(blob, 0)
    temp=[]

    # Finding the position of index finger	
    for i in range(blob_count):	
       my_enum_blob = myblobs.GetBlob(i)
       temp.append(my_enum_blob.MaxX())
    print temp
    for i in range(len(temp)):
         if temp[i]==max(temp):
             print temp[i]
             my_enum_blob = myblobs.GetBlob(i)
             my_enum_blob.FillBlob(blob,CV_RGB(255,0,255),0,0)

    cvNamedWindow("Blob")
    cvShowImage("Blob", blob)
    
    # Finding the centroid
    moments=CvMoments()
    cvMoments(blob,moments,1)
    M00 = cvGetSpatialMoment( moments, 0, 0 )
    M10 = cvGetSpatialMoment( moments, 1, 0 )
    M01 = cvGetSpatialMoment( moments, 0, 1 )
    # Calculating X-cordinate on the window
    wx = int(M10/M00)
    # Calculating Y-cordinate on the window
    wy = int(M01/M00)
    
    
    # Relatively adjust the mouse position by collecting the previous point.
    prev_wx=m.position()[0]/2.2
    prev_wy=m.position()[1]/2
    
    # Mapping X-cordinate on the window to the screen
    vx=int(m.position()[0]+((wx-prev_wx)*2.1))
    
    # Mapping Y-cordinate on the window to the screen
    vy=int(m.position()[1]+((wy-prev_wy)*1.5))

################################# ACTIONS ##############################################################

    # Move the mouse pointer if only Index Finger used
    if blob_count==1:
       count=0
       m.release(vx,vy)
       m.move(vx,vy)
       prev_vx=int(vx)
       prev_vy=int(vy)

    # Click at the position of index finger if two fingers used
    if blob_count==2:
       count=count+1
       if count>1:
         m.move(vx,vy)
       else:
         m.press(prev_vx,prev_vy)
    # Right Click if three fingers used			
    if blob_count==3:
       	m.click(vx,vy,2)
    
    
